'use client';

import { createContext, useContext, useState, useEffect, ReactNode } from 'react';
import { Customer, Admin, LoginResponse } from '@/types';
import { customerApi, adminApi } from '@/services/api';
import { Message } from '@arco-design/web-react';
import { useRouter } from 'next/navigation';

// 用户类型
type UserType = 'customer' | 'admin' | null;

// 认证上下文接口
interface AuthContextType {
  user: Customer | Admin | null;
  userType: UserType;
  login: (username: string, password: string, type: 'customer' | 'admin') => Promise<boolean>;
  logout: () => void;
  isAuthenticated: boolean;
  isLoading: boolean;
  refreshUserInfo: () => Promise<void>;
}

// 创建认证上下文
const AuthContext = createContext<AuthContextType | undefined>(undefined);

interface AuthState {
  user: Customer | Admin | null;
  userType: 'customer' | 'admin' | null;
  isAuthenticated: boolean;
  token: string | null;
  tokenExpiration: number | null;
}

// 认证提供者组件
export function AuthProvider({ children }: { children: ReactNode }) {
  const [state, setState] = useState<AuthState>(() => {
    // 从 localStorage 获取初始状态
    const token = localStorage.getItem('token');
    const userType = localStorage.getItem('userType') as 'customer' | 'admin' | null;
    const user = localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user')!) : null;
    const tokenExpiration = localStorage.getItem('tokenExpiration') ? parseInt(localStorage.getItem('tokenExpiration')!) : null;

    console.log('AuthContext 初始化 localStorage 读取:', { token: !!token, userType, user: !!user, tokenExpiration });

    // 检查 token 是否过期
    const isTokenExpired = tokenExpiration && Date.now() > tokenExpiration;

    const initialState = {
      user: isTokenExpired ? null : user,
      userType: isTokenExpired ? null : userType,
      isAuthenticated: !isTokenExpired && !!token,
      token: isTokenExpired ? null : token,
      tokenExpiration: isTokenExpired ? null : tokenExpiration
    };

    console.log('AuthContext 初始化状态:', initialState);

    return initialState;
  });

  const router = useRouter();

  // 初始化时检查token并获取用户信息
  useEffect(() => {
    console.log('AuthContext useEffect - 首次挂载检查');
    const token = localStorage.getItem('token');
    const storedUserType = localStorage.getItem('userType') as UserType;

    console.log('AuthContext useEffect - localStorage 检查:', { token: !!token, userType: storedUserType });

    if (token && storedUserType) {
      console.log('发现已存储的登录信息，尝试恢复会话...');
      // 确保状态同步，虽然setState是异步的，这里更新通常足够快
      setState(prev => ({
        ...prev,
        isAuthenticated: true,
        userType: storedUserType,
        // 在 refreshUserInfo 中获取并设置完整的 user 对象
        user: null
      }));
      // 立即触发用户信息刷新
      refreshUserInfo();
    } else {
      console.log('未发现登录信息，用户未登录');
    }
  }, []); // 空依赖数组，只在组件首次挂载时运行一次

  // 监听 401 错误
  useEffect(() => {
    const handleUnauthorized = () => {
      console.log('检测到未授权错误，执行登出操作');
      logout();
      router.push('/login');
    };

    window.addEventListener('unauthorized', handleUnauthorized);
    return () => {
      window.removeEventListener('unauthorized', handleUnauthorized);
    };
  }, [router]);

  // 刷新用户信息
  const refreshUserInfo = async () => {
    console.log('AuthContext: refreshUserInfo 被调用');
    const storedUserType = localStorage.getItem('userType') as UserType;
    const token = localStorage.getItem('token');

    if (!storedUserType || !token) {
      console.log('刷新用户信息失败：未找到用户类型或token');
      // 如果是因为token过期或无效，这里不会触发 logout，由 api.ts 中的 401 处理
      return;
    }

    console.log('开始刷新用户信息...', { userType: storedUserType });

    try {
      if (storedUserType === 'customer') {
        // 获取当前登录的客户信息
        const response = await customerApi.getCurrentUser();
        console.log('获取客户信息响应:', response);

        if (response.code === 200 && response.data) {
          setState(prev => ({
            ...prev,
            user: response.data,
            userType: 'customer'
          }));
          console.log('客户信息已更新');
        } else {
          console.error('获取用户信息失败:', response.message);
          // 只有在明确收到 401 错误时才登出
          if (response.code === 401) {
            logout();
          }
        }
      } else if (storedUserType === 'admin') {
        // 获取当前登录的管理员信息
        const response = await adminApi.getCurrentUser();
        console.log('获取管理员信息响应:', response);

        if (response.code === 200 && response.data) {
          setState(prev => ({
            ...prev,
            user: response.data,
            userType: 'admin'
          }));
          console.log('管理员信息已更新');
        } else {
          console.error('获取用户信息失败:', response.message);
          // 只有在明确收到 401 错误时才登出
          if (response.code === 401) {
            logout();
          }
        }
      }
    } catch (error) {
      console.error('获取用户信息错误:', error);
      // 只有在明确收到 401 错误时才登出
      if (error instanceof Error && error.message.includes('401')) {
        logout();
      }
    }
  };

  // 设置 token 和过期时间
  const setToken = (token: string) => {
    const expirationTime = Date.now() + 86400000; // 24小时后过期
    localStorage.setItem('token', token);
    localStorage.setItem('tokenExpiration', expirationTime.toString());
    setState(prev => ({
      ...prev,
      token,
      tokenExpiration: expirationTime
    }));
  };

  // 清除 token 和过期时间
  const clearToken = () => {
    localStorage.removeItem('token');
    localStorage.removeItem('tokenExpiration');
    setState(prev => ({
      ...prev,
      token: null,
      tokenExpiration: null
    }));
  };

  // 检查 token 是否过期
  const checkTokenExpiration = () => {
    if (state.tokenExpiration && Date.now() > state.tokenExpiration) {
      logout();
      return true;
    }
    return false;
  };

  // 定期检查 token 是否过期
  useEffect(() => {
    const interval = setInterval(() => {
      checkTokenExpiration();
    }, 60000); // 每分钟检查一次

    return () => clearInterval(interval);
  }, [state.tokenExpiration]);

  // 登录函数
  const login = async (username: string, password: string, type: 'customer' | 'admin'): Promise<boolean> => {
    console.log('AuthContext: login 被调用', { username, type });
    try {
      console.log('开始登录流程...', { username, type });

      const response = type === 'customer'
        ? await customerApi.login(username, password)
        : await adminApi.login(username, password);

      console.log('登录响应:', response);

      if (response.code === 200 && response.data) {
        console.log('登录成功响应，开始处理数据...');
        // 如果返回的是 token 字符串
        if (typeof response.data === 'string') {
          const token = response.data;

          console.log('提取到 Token:', token);

          // 保存 token 和过期时间
          setToken(token);

          // 保存用户类型
          localStorage.setItem('userType', type);

          // 更新本地状态 (确保先设置认证状态，再获取用户信息)
          setState(prev => ({
            ...prev,
            userType: type,
            isAuthenticated: true,
            token,
            tokenExpiration: Date.now() + 86400000, // 24小时过期
            // 暂时清空 user，等待 refreshUserInfo 获取最新完整信息
            user: null
          }));

          console.log('AuthContext: 登录成功状态已更新，触发 refreshUserInfo');

          // 获取用户信息
          await refreshUserInfo(); // 使用 await 确保用户信息获取完成后再跳转

          console.log('AuthContext: refreshUserInfo 完成，准备跳转');

          // 根据用户类型跳转到不同页面
          if (type === 'customer') {
            router.push('/rooms');
          } else if (type === 'admin') {
            router.push('/admin/bookings');
          }

          return true; // 登录成功
        } else {
          // 如果 response.data 不是字符串，可能是后端返回了其他结构
          console.error('登录响应数据格式不正确，response.data 不是字符串:', response.data);
          // Message.error('登录失败: 响应数据格式错误');
          return false;
        }
      } else {
        console.error('登录失败响应:', response);
        // Message.error(response.message || '登录失败，请检查用户名或密码');
        // 如果是 401 错误，api.ts 中的处理函数会触发登出
        return false;
      }
    } catch (error) {
      console.error('登录过程中发生错误:', error);
      // Message.error(error instanceof Error ? error.message : '登录过程中发生未知错误');
      return false;
    }
  };

  // 登出函数
  const logout = () => {
    console.log('AuthContext: 执行登出操作');
    clearToken();
    localStorage.removeItem('userType');
    localStorage.removeItem('user'); // 清除用户信息缓存
    setState(prev => ({
      ...prev,
      user: null,
      userType: null,
      isAuthenticated: false
    }));
    // 不在这里直接跳转，由 api.ts 的 401 监听器处理跳转
    // router.push('/login');
  };

  // 提供认证上下文
  return (
    <AuthContext.Provider value={{
      user: state.user,
      userType: state.userType,
      login,
      logout,
      isAuthenticated: state.isAuthenticated,
      isLoading: false,
      refreshUserInfo
    }}>
      {children}
    </AuthContext.Provider>
  );
}

// 自定义钩子，用于在组件中访问认证上下文
export function useAuth() {
  const context = useContext(AuthContext);

  if (context === undefined) {
    throw new Error('useAuth 必须在 AuthProvider 内部使用');
  }

  return context;
}